<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <Header @addTodo="addTodo($event)"/> <!-- 给子组件对象绑定自定义事件监听 -->
      <Header ref="header"/>
      <List :todos="todos" :toggleTodo="toggleTodo"/>
      <Footer :todos="todos" :selectAll="selectAll" :clearCompletedTodos="clearCompletedTodos"/>

      <hr>
      <!-- <props-test name="tom" :myAge="-1"/> -->

      <SlotTest>
        <!-- <p>写什么啊!!!!</p> -->
        <!-- 模板是在父组件编译好再传递给子组件的 -->
        <template slot="second">
          <h3>{{title}}</h3>
        </template>
        
        <h2 slot="first">atguigu</h2>
      </SlotTest>
      <hr>


      <h2>效果一: 显示TODO列表时, 已完成的TODO为绿色</h2>
      <TodoList :todos="todos">
        <!-- <span>xxxx</span> -->
        <!-- v-slot指定了一接收slot回传过来的所有属性数据的对象 -->
        <template v-slot="scope">
          <span :style="{color: scope.row.completed ? 'green': ''}">{{scope.row.title}}</span>
        </template>
        
      </TodoList>

      <h2>效果二: 显示TODO列表时, 带序号, TODO的颜色为蓝绿搭配</h2>
      <TodoList :todos="todos">
        <h3>yyyyy</h3>
        <template v-slot="{row, $index}">
          <span :style="{color: $index%2===1? 'green': 'blue'}">{{$index + 1}} {{row.title}}</span>
        </template>
      </TodoList>
    </div>
  </div>
</template>


<script>
  import PubSub from 'pubsub-js'
  import Vue from 'vue'
  import Header from './components/Header.vue'
  import List from './components/List.vue'
  import Footer from './components/Footer.vue'
  import PropsTest from './test/PropsTest.vue'
  import SlotTest from './test/SlotTest.vue'
  import TodoList from './test/TodoList.vue'

  export default {
    name: 'App',

    data () {
      return {
        // 初始时就读取json数据并解析为js的数组, 如果没有指定为空数组
        todos: [],
        title: 'abcd'
      }
    },


    mounted () {

      // console.log(this.constructor)
      // console.dir(Vue)
      // console.log(this)
      console.log(Vue.prototype===this.__proto__.__proto__)


      // 模拟异步加载得到todos数据
      setTimeout(() => {
        this.todos = JSON.parse(localStorage.getItem('todos_key')) || []
      }, 2000);

      // 给header组件对象绑定addTodo事件
      this.$refs.header.$on('addTodo',this.addTodo)
      // this.$on('addTodo',this.addTodo)  // 只能是给header组件添加才行

      // 给事件总线绑定自定义事件监听
      this.$globalEventBus.$on('deleteTodo',this.deleteTodo)
      //  this.$globalEventBus.deleteTodo()
      // this.$globalEventBus.$on('deleteTodo', (index) =>  {
      //   console.log('---', this)
      //   this.deleteTodo(index)
      // })

      // 订阅消息
      this.token = PubSub.subscribe('toggleTodo', (msg, todo) => {
        this.toggleTodo(todo)
      })
    },


    // 在组件死亡前, 解绑自定义事件监听
    beforeDestroy () {
      // this.$refs.header.$off('addTodo')  // 当前情况其实没有必要
      this.$globalEventBus.$off('deleteTodo')
      // 取消订阅
      PubSub.unsubscribe(this.token)
    },

    watch: {
      todos: {
        handler (value) {
          console.log('handler', value)
          // 将todos保存localStorage中 (必须保存json格式)
          localStorage.setItem('todos_key', JSON.stringify(value))
        },
        deep: true, // 深度监视 ==> 数组内部的对象内部数据变化都会触发
      }
    },

    // 数据在哪个组件, 更新数据的行为(函数)就定义在哪个组件
    methods: {
      // 添加todo
      addTodo (todo) {
        console.log('addTodo', todo)
        // 创建一个新的id, 并给todo
        todo.id = Date.now()
        // 添加到todos中
        this.todos.unshift(todo)
      },

      // 删除todo
      deleteTodo (index) {
        this.todos.splice(index, 1)
      },

      // 全选或全不选
      selectAll(isCheck) {
        this.todos.forEach(todo => todo.completed = isCheck)
      },

      // 消除已完成的
      clearCompletedTodos () {
        console.log('clearCompletedTodos()')
        this.todos = this.todos.filter(todo => !todo.completed)
      },
      // 将一个指定的todo切换勾选状态
      toggleTodo (todo) {
        todo.completed = !todo.completed
      }
    },

    components: {
      Header,
      List,
      Footer,
      PropsTest,
      SlotTest,
      TodoList
    }
  }
</script>


<style scoped>
  .todo-container {
    width: 600px;
    margin: 0 auto;
  }
  .todo-container .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
</style>